/* 向线程传递参数饼返回值
 * 线程的创建者在创建线程时可能会用指向void的指针给线程传递单个参数。
 * 要传递多个值，创建者必须使用指向数组或结构的指针
 * 该程序中说明了如何传递一个指向数组的指针。main程序将包含两个打开的文件描述
 * 的数组传递给一个运行copyfilenpass函数的线程
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "restart.h"

#define PERMS (S_IRUSR | S_IWUSR)
#define READ_FLAGS O_RDONLY
#define WRITE_FLAGS (O_WRONLY | O_CREAT | O_TRUNC)

/* 该程序中可以通过数组或者通过pthread_join函数的第二个参数检索这个值，
   callcopypass还可以传递一个长度为2的数组，线程可以在某个输入文件描述符上保存返回值*/
void *copyfilepass(void *arg);

/* 将fromfile复制到tofile*/
int main (int argc, char *argv[]) {
    int *bytesptr;
    int error;
    int fds[2];
    pthread_t tid;

    if (argc != 3) {
        fprintf(stderr, "Usage: %s fromfile tofile\n", argv[0]);
        return 1;
    }

    if ((fds[0] = open(argv[1], READ_FLAGS) == -1 ) ||
        (fds[1] = open(argv[2],WRITE_FLAGS) == -1) ) {
            perror("Failed to open the files");
            return 1;
        }
    
    /* 创建线程*/
    if (error = pthread_create(&tid, NULL, copyfilepass, fds)) {
        fprintf(stderr, "Failed to create thread: %s\n", strerror(error));
        return 1;
    }

    /* 将线程阻塞*/
    if (error = pthread_join(tid, (void **)&bytesptr)) {
        fprintf(stderr, "Failed to join thread: %s\n", strerror(error));
        return 1;
    }

    printf("Number of bytes copied: %d\n", *bytesptr);
    return 0;
}

void *copyfilepass(void *arg) {
    int *argint;

    argint = (int *)arg;
    argint[2] = copyfile(argint[0], argint[1]);
    close(argint[0]);
    close(argint[1]);

    return argint + 2;
}